package gov.pbc.nn.kjgl.maintenance.view;


import gov.pbc.nn.core.dao.CommonHibernateDao;
import gov.pbc.nn.core.dao.CommonJdbcDao;
import gov.pbc.nn.core.dao.PbcnnCoreHibernateDao;
import gov.pbc.nn.core.dao.PbcnnCoreJdbcDao;
import gov.pbc.nn.kjgl.maintenance.entity.SysEmergencyPlan;
import gov.pbc.nn.kjgl.maintenance.entity.SysEmergencyRehearsal;
import gov.pbc.nn.kjgl.maintenance.entity.SysEmergencyRehearsalRecord;
import gov.pbc.nn.kjgl.maintenance.entity.SysEmergencyRehearsalStep;
import gov.pbc.nn.kjgl.maintenance.entity.SysEmergencyScheme;
import gov.pbc.nn.kjgl.maintenance.entity.SysEntity;
import gov.pbc.nn.kjgl.maintenance.entity.SysMaterial;
import gov.pbc.nn.kjgl.maintenance.handler.SysCTOAssignmentHandler;
import gov.pbc.nn.uflo.UfloUtils;
import gov.pbc.nn.uflo.entity.Opinion;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.bstek.bdf2.core.business.IUser;
import com.bstek.bdf2.core.context.ContextHolder;
import com.bstek.dorado.annotation.DataProvider;
import com.bstek.dorado.annotation.DataResolver;
import com.bstek.dorado.annotation.Expose;
import com.bstek.dorado.core.Configure;
import com.bstek.dorado.data.entity.EntityState;
import com.bstek.dorado.data.entity.EntityUtils;
import com.bstek.dorado.data.provider.Criteria;
import com.bstek.dorado.data.provider.Page;
import com.bstek.dorado.uploader.UploadFile;
import com.bstek.dorado.uploader.annotation.FileResolver;
import com.bstek.uflo.client.service.ProcessClient;
import com.bstek.uflo.client.service.TaskClient;
import com.bstek.uflo.model.task.Task;
import com.bstek.uflo.service.StartProcessInfo;
import com.bstek.uflo.service.TaskOpinion;

/**
 * 应急演练视图对应的处理类
 * @author YY
 *
 */
@Component
public class SysEmergencyRehearsalPR_old{
	
	@Resource(name = CommonHibernateDao.BEAN_ID)
	private CommonHibernateDao hibernateDao;
	@Resource(name = CommonJdbcDao.BEAN_ID)
	private CommonJdbcDao jdbcDao;
	@Resource(name = PbcnnCoreHibernateDao.BEAN_ID)
	private PbcnnCoreHibernateDao coreHibernateDao;
	@Resource(name = PbcnnCoreJdbcDao.BEAN_ID)
	private PbcnnCoreJdbcDao pbcnnCoreJdbcDao;
	@Resource(name = ProcessClient.BEAN_ID)
	private ProcessClient processClient;
	@Resource(name = TaskClient.BEAN_ID)
	private TaskClient taskClient;
	
	public static final String PROCESS_NAME = "应急演练";
	
	/**
	 * 为dataSetSysEmergencyRehearsal提供分页获取方法
	 * @param page
	 * @throws Exception
	 */
	@DataProvider
	public void loadEmergencyRehearsalPage(Page<SysEmergencyRehearsal> page,Criteria criteria) throws Exception{
		
		DetachedCriteria detachedCriteria = this.hibernateDao.buildDetachedCriteria(
				criteria, SysEmergencyRehearsal.class);
		detachedCriteria.add(Restrictions.or(Restrictions.eq("invalid", false),
				Restrictions.isNull("invalid")));
		this.hibernateDao.pagingQuery(page, detachedCriteria);
	}
	
	/**
	 * 为dataSetSysEmergencyRehearsal提供获取方法
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@DataProvider
	public SysEmergencyRehearsal loadEmergencyRehearsal(String businessId){
		
		if (!StringUtils.isEmpty(businessId)) {
			DetachedCriteria detachedCriteria = DetachedCriteria
					.forClass(SysEmergencyRehearsal.class);
			detachedCriteria.add(Restrictions.or(Restrictions.eq("invalid", false),
					Restrictions.isNull("invalid")));
			detachedCriteria.add(Restrictions.eq("id", businessId));
			List<SysEmergencyRehearsal> ls = (List<SysEmergencyRehearsal>) this.hibernateDao
					.query(detachedCriteria);
			if (!ls.isEmpty()) {
				return ls.get(0);
			}
		}
		
		return null;
	}
	/**
	 * 为dataSetSysEmergencyRehearsal提供获取方法
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@DataProvider
	public Collection<SysEmergencyRehearsalStep> loadEmergencyRehearsalStep(String businessId){
		
		if (!StringUtils.isEmpty(businessId)) {
			DetachedCriteria detachedCriteria = DetachedCriteria
					.forClass(SysEmergencyRehearsalStep.class);
			detachedCriteria.add(Restrictions.or(Restrictions.eq("invalid", false),
					Restrictions.isNull("invalid")));
			detachedCriteria.add(Restrictions.eq("epId", businessId));
			List<SysEmergencyRehearsalStep> list = (List<SysEmergencyRehearsalStep>) this.hibernateDao
					.query(detachedCriteria);
			if (!list.isEmpty()) {
				return list;
			}
		}
		return null;
	}
	/**
	 * 为dataSetSysEmergencyRehearsalRecord提供获取方法
	 * @param businessId
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@DataProvider
	public Collection<SysEmergencyRehearsalRecord> loadSysEmergencyRehearsalRecord(String businessId){
		
		DetachedCriteria detachedCriteria = DetachedCriteria
				.forClass(SysEmergencyRehearsalRecord.class);
		detachedCriteria.add(Restrictions.or(Restrictions.eq("invalid", false),
				Restrictions.isNull("invalid")));
		detachedCriteria.add(Restrictions.eq("epId", businessId));
		List<SysEmergencyRehearsalRecord> list = (List<SysEmergencyRehearsalRecord>) this.hibernateDao
				.query(detachedCriteria);
		if (!list.isEmpty()) {
			return list;
		}else {
			return null;
		}
		
	}
	
	/**
	 * 获取系统ID对应的SysEmergencyPlan
	 * @param sysId
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@DataProvider
	public Collection<SysEmergencyPlan> loadSysEmergencyPlan(String sysId,String filter) {
		
		DetachedCriteria detachedCriteria = DetachedCriteria.forClass(SysEmergencyPlan.class);
		detachedCriteria.add(Restrictions.or(Restrictions.eq("invalid", false), Restrictions.isNull("invalid")));
		detachedCriteria.add(Restrictions.eq("state", 10));
		
		if (filter != null && !StringUtils.isEmpty(filter)) {
			detachedCriteria.add(Restrictions.like("title", filter));
		}
		if (sysId != null) {
			detachedCriteria.add(Restrictions.eq("sysId", sysId));
		}else{
			return null;
		}
		return (Collection<SysEmergencyPlan>) this.hibernateDao.query(detachedCriteria);
	}
	
	/**
	 * 获取演练planId对应的SysEmergencyPlan
	 * @param sysId
	 * @return
	 */
	 
	@SuppressWarnings("unchecked")
	@Expose
	public String ajaxActionQueryPlan(String planId) {
		
		DetachedCriteria detachedCriteria = DetachedCriteria.forClass(SysEmergencyPlan.class);
		detachedCriteria.add(Restrictions.or(Restrictions.eq("invalid", false), Restrictions.isNull("invalid")));
		if (planId != null) {
			detachedCriteria.add(Restrictions.eq("id", planId));
			List<SysEmergencyPlan> sysEmergencyPlans = (List<SysEmergencyPlan>) this.hibernateDao.query(detachedCriteria);
			if (sysEmergencyPlans.size() > 0) {
				return sysEmergencyPlans.get(0).getTitle();
			}else{
				return null;
			}
		}else{
			return null;
		}
	}
	/**
	 * 获取系统ID对应的SysEmergencyScheme
	 * @param sysId
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@DataProvider
	public Collection<SysEmergencyScheme> loadSysEmergencyScheme(String sysId,String filter) {
		
		DetachedCriteria detachedCriteria = DetachedCriteria.forClass(SysEmergencyScheme.class);
		detachedCriteria.add(Restrictions.or(Restrictions.eq("invalid", false), Restrictions.isNull("invalid")));
		detachedCriteria.add(Restrictions.eq("state", 10));
		if (filter != null && !StringUtils.isEmpty(filter)) {
			detachedCriteria.add(Restrictions.like("title", filter));
		}
		if (sysId != null) {
			detachedCriteria.add(Restrictions.eq("sysId", sysId));
		}else{
			return null;
		}
		return (Collection<SysEmergencyScheme>) this.hibernateDao.query(detachedCriteria);
	}
	
	/**
	 * 获取演练schemeId对应的SysEmergencyPlan
	 * @param sysId
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@Expose
	public String ajaxActionQueryScheme(String schemeId) {
		
		DetachedCriteria detachedCriteria = DetachedCriteria.forClass(SysEmergencyScheme.class);
		detachedCriteria.add(Restrictions.or(Restrictions.eq("invalid", false), Restrictions.isNull("invalid")));
		if (schemeId != null) {
			detachedCriteria.add(Restrictions.eq("id", schemeId));
			List<SysEmergencyScheme> sysEmergencySchemes = (List<SysEmergencyScheme>) this.hibernateDao.query(detachedCriteria);
			if (sysEmergencySchemes.size() > 0) {
				return sysEmergencySchemes.get(0).getTitle();
			}else{
				return null;
			}
		}else{
			return null;
		}
	}
	/**
	 * 保存演练信息和演练步骤数据
	 * @param sysEmergencyRehearsal
	 * @param sysEmergencyRehearsalStep
	 * @throws Exception
	 */
	@Transactional
	@DataResolver
	public void saveAction(SysEmergencyRehearsal sysEmergencyRehearsal,Collection<SysEmergencyRehearsalStep> sysEmergencyRehearsalSteps ) throws Exception{
		
		if (EntityUtils.getState(sysEmergencyRehearsal).equals(EntityState.NEW)) {
			this.hibernateDao.save(sysEmergencyRehearsal);
		}
		else if (EntityUtils.getState(sysEmergencyRehearsal).equals(EntityState.MODIFIED)) {
			this.hibernateDao.update(sysEmergencyRehearsal);
		}
		else if (EntityUtils.getState(sysEmergencyRehearsal).equals(EntityState.DELETED)) {
			this.hibernateDao.delete(sysEmergencyRehearsal);
		}
		
		for (SysEmergencyRehearsalStep sysEmergencyRehearsalStep : sysEmergencyRehearsalSteps) {
			if (EntityUtils.getState(sysEmergencyRehearsalStep).equals(EntityState.NEW)) {
					sysEmergencyRehearsalStep.setEpId(sysEmergencyRehearsal.getId());
					this.hibernateDao.save(sysEmergencyRehearsalStep);
			}
			else if (EntityUtils.getState(sysEmergencyRehearsalStep).equals(EntityState.MODIFIED)) {
					sysEmergencyRehearsalStep.setEpId(sysEmergencyRehearsal.getId());
					this.hibernateDao.update(sysEmergencyRehearsalStep);
			}
			else if (EntityUtils.getState(sysEmergencyRehearsalStep).equals(EntityState.DELETED)) {
					sysEmergencyRehearsalStep.setEpId(sysEmergencyRehearsal.getId());
					this.hibernateDao.delete(sysEmergencyRehearsalStep);
			}
		}
		
	}
	/**
	 * 保存并提交演练记录信息
	 * @param taskId
	 * @param sysEmergencyRehearsalRecords
	 * @param businessId
	 * @return
	 */
	@Transactional
	@DataResolver
	public void saveTjAction(Collection<SysEmergencyRehearsalRecord> sysEmergencyRehearsalRecords,String taskId){
		
		Task task = taskClient.getTask(Long.valueOf(taskId));
		String businessId = task.getBusinessId();
		taskClient.start(Long.valueOf(taskId));
		
		for (SysEmergencyRehearsalRecord sysEmergencyRehearsalRecord : sysEmergencyRehearsalRecords) {
			System.out.println(EntityUtils.getState(sysEmergencyRehearsalRecord));
			if (EntityUtils.getState(sysEmergencyRehearsalRecord).equals(EntityState.NEW)) {
				sysEmergencyRehearsalRecord.setEpId(businessId);
				this.hibernateDao.save(sysEmergencyRehearsalRecord);
			}else if (EntityUtils.getState(sysEmergencyRehearsalRecord).equals(EntityState.MODIFIED)) {
				this.hibernateDao.update(sysEmergencyRehearsalRecord);
			}else if (EntityUtils.getState(sysEmergencyRehearsalRecord).equals(EntityState.DELETED)) {
				this.hibernateDao.delete(sysEmergencyRehearsalRecord);
			}
		}
		
		taskClient.complete(Long.valueOf(taskId));
	}
	
	/**
	 * 开启流程
	 * @param bussinessId
	 * @param agree
	 * @throws Exception
	 */
	@Transactional
	@Expose
	public void startProcess(Map<String, Object> params) throws Exception{
		
		String cto = params.get("cto").toString();
		String businessId = params.get("businessId").toString();
		String sysId = params.get("sysId").toString();
		int agree = Integer.valueOf(params.get("agree").toString());
		
		StartProcessInfo info = new StartProcessInfo();
		info.setBusinessId(businessId);
		info.setCompleteStartTask(true);
		info.setPromoter(ContextHolder.getLoginUserName());
		
		Map<String, Object> variables = new HashMap<String,Object>();
		variables.put("cto", cto);
		variables.put("agree", agree);
		variables.put("sysId", sysId);
		
		info.setVariables(variables);
		this.processClient.startProcessByName(PROCESS_NAME, info);
	}
/*	
	*//**
	 * 判断当前要发起流程的业务的businessId是否正处于一个流程实例中
	 * 
	 * @return
	 *//*
	private boolean isInProcess(String businessId) {
		return UfloUtils.isInProcessInstance(businessId);
	}
	*/
	
	/**
	 * 判断是否可以开始流程
	 * @param id
	 * @return
	 */
	@Expose
	public String canStartProcess(String id) {
//		if (UfloUtils.isInProcessInstance(id)) {
//			return "当前演练正在审批过程中，不能再次发起！";
//		}
//		if (UfloUtils.hasHistoryProcessInstance(id)) {
//			return "当前演练已经审批完成，不能再次发起！";
//		}
		return null;
	}
	
	/**
	 * 为ajaxActionCanModify提供方法
	 * @param id
	 * @return
	 */
	@Expose
	public String canModify(String id) {
//		if (UfloUtils.isInProcessInstance(id)) {
//			return "当前演练正在审批过程中，不能修改！";
//		}
//		if (UfloUtils.hasHistoryProcessInstance(id)) {
//			return "当前演练已经审批完成，不能修改！";
//		}
		return null;
	}
	
	/**
	 * 为ajaxActionCanDelete提供方法
	 * @param id
	 * @return
	 */
	@Expose
	public String canDelete(String id) {
//		if (UfloUtils.isInProcessInstance(id)) {
//			return "当前演练正在审批过程中，不能删除！";
//		}
//		if (UfloUtils.hasHistoryProcessInstance(id)) {
//			return "当前演练已经审批完成，不能删除！";
//		}
		return null;
	}
	
	@Expose
	@Transactional
	public void deleteSysEmergencyRehearsal(String id) {
		this.hibernateDao.delete(id, SysEmergencyRehearsal.class);
		
	}
	
	/**
	 * 获取系统主管
	 * 
	 * @param sysId
	 * @return
	 */
	@DataProvider
	public List<Map<String, Object>> loadCTO(String sysId) {
		SysCTOAssignmentHandler handler = ContextHolder
				.getBean(SysCTOAssignmentHandler.BEAN_ID);
		List<IUser> list = handler.getCTO(sysId);
		List<Map<String, Object>> users = new ArrayList<Map<String, Object>>();
		for (IUser u : list) {
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("username", u.getUsername());
			map.put("cname", u.getCname());
			users.add(map);
		}
		return users;
	}
	
	/**
	 * 加载系统信息。根据当前登录人是运维人员或某系统的业务人员加载
	 * 
	 * @param filter
	 * @return
	 */
	@DataProvider
	public List<Map<String, Object>> getSysEntities(String filter) {
		String sql = "select DISTINCT e.id_ as id,e.name_ as name,s.ab_ as ab from t_sys_entity e left join t_sys_operation_staff s on e.ID_=s.SYS_ID_ and s.USERNAME_=? ";
		Object[] param = null;
		if (StringUtils.isEmpty(filter)) {
			param = new Object[] { ContextHolder.getLoginUserName() };
		} else {
			sql += " where e.NAME_ LIKE ?";
			param = new Object[] { ContextHolder.getLoginUserName(),
					filter + "%" };
		}
		List<Map<String, Object>> mapList = this.jdbcDao.getJdbcTemplate()
				.queryForList(sql, param);
		if (mapList.size() > 0) {

			List<String> sysIds = new ArrayList<String>();
			for (Map<String, Object> m : mapList) {
				sysIds.add((String) m.get("id"));
			}
			String hql = "select new map(e.id AS id,e.name as name) from "
					+ SysEntity.class.getName()
					+ " e where e.operationDeptId=:deptId and e.id not in :sysIds";
			Map<String, Object> m = new HashMap<String, Object>();
			m.put("deptId", ContextHolder.getLoginUser().getDepts().get(0)
					.getId());
			m.put("sysIds", sysIds);
			List<Map<String, Object>> mapList2 = this.hibernateDao
					.query(hql, m);
			mapList.addAll(mapList2);
		}

		return mapList;
	}
	
	/**
	 * 保存审批意见
	 * 
	 * @param taskId
	 * @param opinionText
	 * @param i
	 */
	@Transactional
	@Expose
	public void opinionSh(Map<String, Object> params) {
		
		
		long taskId = Long.parseLong(params.get("taskId").toString());
		String opinionText = params.get("opinionText").toString();
		int agree = Integer.parseInt(params.get("agree").toString());
		Task task = taskClient.getTask(taskId);
		TaskOpinion option = new TaskOpinion(opinionText);
		taskClient.start(Long.valueOf(taskId));
		final Opinion o = new Opinion();
		o.setProcessInstanceId(task.getProcessInstanceId());
		o.setBusKey(task.getBusinessId());
		o.setTaskId(taskId);
		o.setTaskName(task.getTaskName());
		o.setNodeName(task.getNodeName());
		o.setProcessName("应急演练");
		o.setBusTable("T_SYS_EMERGENCY_PLAN");
		o.setOpinion(opinionText);
		o.setUsername(ContextHolder.getLoginUser().getUsername());
		o.setDeptId(ContextHolder.getLoginUser().getDepts().get(0).getId());
		o.setDeptName(ContextHolder.getLoginUser().getDepts().get(0).getName());
		o.setCname(ContextHolder.getLoginUser().getCname());
		this.coreHibernateDao.save(o);
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("agree", agree);
		taskClient.complete(Long.valueOf(taskId), map, option);
		
	}
	
	/**
	 * 再次提交
	 * 
	 * @param taskId
	 */
	@Transactional
	@Expose
	public void commitAgain(String taskId) {
			taskClient.start(Long.valueOf(taskId));
			taskClient.complete(Long.valueOf(taskId));
	}
	
	/**
	 * 撤销申请
	 * 
	 * @param taskId
	 */
	@Transactional
	@Expose
	public void cheXiao(String taskId) {
		taskClient.start(Long.valueOf(taskId));
		taskClient.forward(Long.valueOf(taskId), "归档");
	}

	/**
	 * 
	 * @param file
	 * @param params
	 * @return
	 * @throws Exception
	 */
	@Transactional
	@FileResolver
	public void process(UploadFile file, Map<String, Object> params)
			throws Exception {
		
		int type = Integer.valueOf(params.get("type").toString());
		String businessId = params.get("businessId").toString();
		String sysId = params.get("sysId").toString();
		String sysName = params.get("sysName").toString();

		String basePath = Configure.getString("SYS_YUNWEI_FILE_UPLOAD_PATH");
		if (StringUtils.isEmpty(basePath)) {
			throw new IllegalArgumentException("必须指定档案文件上传的基本地址");
		}
		String pathArr = getFileNameByType(Integer.valueOf(type));
		try {
			Path path = Paths.get(basePath, pathArr);
			if (!Files.isDirectory(path)) {
				path = Files.createDirectories(path);
			}
			path = path.resolve(UUID.randomUUID().toString());
			File destFile = Files.createFile(path).toFile();
			// 保存sysMaterial表格，type设置成10，10是演练报告的意思
			SysMaterial sysMaterial = new SysMaterial();
			sysMaterial.setPath(path.toString());
			sysMaterial.setFileName(file.getFileName());
			sysMaterial.setSysId(sysId);
			sysMaterial.setSysName(sysName);
			sysMaterial.setType(type);
			this.hibernateDao.save(sysMaterial);
			// 关联保存到对应的字段
			SysEmergencyRehearsal sysEmergencyRehearsal = loadEmergencyRehearsal(businessId);
			sysEmergencyRehearsal.setUploadId(sysMaterial.getId());
			this.hibernateDao.update(sysEmergencyRehearsal);
			file.transferTo(destFile);
			
		} catch (IllegalStateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 根据合适的类型返回合适的字符串，该字符串表示文件存的路径
	 * @param type
	 * @return"0:事件相关；5：问题相关；10：演练报告
	 */
	private String getFileNameByType(Integer type) {
		String returnVale = null;
		switch (type) {
		case 0:
			returnVale = "事件相关";
			break;
		case 5:
			returnVale = "问题相关";
			break;
		case 10:
			returnVale = "演练报告";
			break;
		}
		return "应急演练文件/" + returnVale;
	}
}
